package com.lantosec.hmrp.core.util;

import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtils {


    /**
     * 1小时3600秒
     */
    static long HOUR_SEC_NUMBER = 3600L;

    /**
     * 1 天 24 * 3600 秒
     */
    static long DAY_SEC_NUMBER = HOUR_SEC_NUMBER * 24;

    /**
     * 1 天 30 * 24 * 3600 秒
     */
    static long MONTH_SEC_NUMBER = DAY_SEC_NUMBER * 30;

    /**
     * 1 年 365 * 24 * 3600 秒
     */
    static long YEAR_SEC_NUMBER = DAY_SEC_NUMBER * 365;

    /**
     * 1小时=3600*1000毫秒 <code>HOUR_MS_UNIT</code>
     */
    final static long HOUR_MS_UNIT = 3600 * 1000;

    public static final String LONGFORMAT = "yyyy-MM-dd HH:mm:ss.SSS";

    /**
     * <code>DEFAULTFORMAT</code>Date长日期格式
     */
    public static final String DEFAULTFORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * <code>SIMPLEFORMATSTRING</code>Date长日期格式(无秒)
     */
    public static final String SIMPLEFORMATSTRING = "yyyy-MM-dd HH:mm";

    public static final String NUMFORMATSTRING = "yyyyMMddHHmm";

    /**
     * <code>SHORTFORMAT</code>Date短日期格式
     */
    public static final String SHORTFORMAT = "yyyy-MM-dd";

    public static final String YYYYMMDD = "yyyyMMdd";

    public static final String YYMMDD = "yyMMdd";

    public static final String YYYYMM = "yyyyMM";

    public static final String YYMM = "yyMM";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YY_MM_DD = "yy-MM-dd";

    public static final String YYYY_MM = "yyyy-MM";

    public static final String YY_MM = "yy-MM";

    /**
     * 得到指定日期
     *
     * @param strDate
     *            日期
     * @param pattern
     *            日期格式
     * @return 日期
     */
    public static java.sql.Date toSqlDateByPattern(String strDate,
                                                   String pattern) {
        try {
            // 得到日期
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            return new java.sql.Date((formatter.parse(strDate)).getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new java.sql.Date(0);
    }

    /**
     * 得到指定日期
     *
     * @param strDate
     *            日期
     * @param pattern
     *            日期格式
     * @return 日期
     */
    public static java.util.Date toDateTimeByPattern(String strDate,
                                                     String pattern) {
        try {
            // 得到日期
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            return new java.util.Date((formatter.parse(strDate)).getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new java.sql.Date(0);
    }

    /**
     * 根据输入的日期长度自动转换成相应长度的Date型日期
     *
     * @param dDate
     *            String
     * @return Date
     */
    public static java.sql.Date toSqlDataTime(String dDate) {
        String dateFormat = SHORTFORMAT;

        if (dDate.length() > 10 && dDate.length() <= 16) {
            dateFormat = SIMPLEFORMATSTRING;
        } else if (dDate.length() > 16 && dDate.length() <= 19) {
            dateFormat = DEFAULTFORMAT;
        } else if (dDate.length() > 19) {
            dateFormat = LONGFORMAT;
        }
        java.sql.Date d1 = toSqlDateByPattern(dDate, dateFormat);

        return d1;
    }

    /**
     * 根据输入的日期长度自动转换成相应长度的Date型日期
     *
     * @param dDate
     *            String
     * @return Date
     */
    public static java.util.Date toDataTime(String dDate) {
        String dateFormat = SHORTFORMAT;
        if (org.apache.commons.lang3.StringUtils.isEmpty(dDate)) {
            return null;
        }

        if (dDate.length() > 10 && dDate.length() <= 16) {
            dateFormat = SIMPLEFORMATSTRING;
        } else if (dDate.length() > 16 && dDate.length() <= 19) {
            dateFormat = DEFAULTFORMAT;
        } else if (dDate.length() > 19) {
            dateFormat = LONGFORMAT;
        }
        java.util.Date d1 = toDateTimeByPattern(dDate, dateFormat);

        return d1;
    }

    /**
     * 得到格式化的日期字符串
     *
     * @param d
     * @return 日期
     */
    public static String toSqlDateString(java.sql.Date d, String pattern) {

        String rs = "";

        try {
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            rs = formatter.format(d);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return isFirstStartDate(rs) ? "" : rs;

    }

    // 检测日期是否是1970-01-01或1899-12-30
    private static boolean isFirstStartDate(String strDate) {
        if (strDate.compareTo("1970-01-01") == 0
                || strDate.compareTo("1899-12-30") == 0
                || strDate.compareTo("1969-12-31") == 0) {
            return true;
        }
        return false;
    }

    /**
     * Return a Timestamp for right now
     *
     * @return Timestamp for right now
     */
    public static java.sql.Timestamp nowTimestamp() {
        return new java.sql.Timestamp(System.currentTimeMillis());
    }

    /**
     * Return a Date for right now
     *
     * @return Date for right now
     */
    public static java.util.Date nowDate() {
        return new java.util.Date();
    }

    public static java.sql.Date nowSqlDate() {
        return new java.sql.Date(nowDate().getTime());
    }

    public static java.sql.Timestamp getDayStart(java.sql.Timestamp stamp) {
        return getDayStart(stamp, 0);
    }

    public static java.sql.Timestamp getDayStart(java.sql.Timestamp stamp,
                                                 int daysLater) {
        Calendar tempCal = Calendar.getInstance();

        tempCal.setTime(new java.util.Date(stamp.getTime()));
        tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH),
                tempCal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        tempCal.add(Calendar.DAY_OF_MONTH, daysLater);
        return new java.sql.Timestamp(tempCal.getTime().getTime());
    }

    public static java.sql.Timestamp getNextDayStart(java.sql.Timestamp stamp) {
        return getDayStart(stamp, 1);
    }

    public static java.sql.Timestamp getDayEnd(java.sql.Timestamp stamp) {
        return getDayEnd(stamp, 0);
    }

    public static java.sql.Timestamp getDayEnd(java.sql.Timestamp stamp,
                                               int daysLater) {
        Calendar tempCal = Calendar.getInstance();

        tempCal.setTime(new java.util.Date(stamp.getTime()));
        tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH),
                tempCal.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        tempCal.add(Calendar.DAY_OF_MONTH, daysLater);
        return new java.sql.Timestamp(tempCal.getTime().getTime());
    }

    /**
     * Converts a date String into a java.sql.Date
     *
     * @param date
     *            The date String: MM/DD/YYYY
     * @return A java.sql.Date made from the date String
     */
    public static java.sql.Date toSqlDate(String date) {
        java.util.Date newDate = toDate(date, "00:00:00");
        return newDate != null ? new java.sql.Date(newDate.getTime()) : null;
    }

    /**
     * Makes a java.sql.Date from separate Strings for month, day, year
     *
     * @param monthStr
     *            The month String
     * @param dayStr
     *            The day String
     * @param yearStr
     *            The year String
     * @return A java.sql.Date made from separate Strings for month, day, year
     */
    public static java.sql.Date toSqlDate(String monthStr, String dayStr,
                                          String yearStr) {
        java.util.Date newDate = toDate(monthStr, dayStr, yearStr, "0", "0",
                "0");
        return newDate != null ? new java.sql.Date(newDate.getTime()) : null;
    }

    /**
     * Makes a java.sql.Date from separate ints for month, day, year
     *
     * @param month
     *            The month int
     * @param day
     *            The day int
     * @param year
     *            The year int
     * @return A java.sql.Date made from separate ints for month, day, year
     */
    public static java.sql.Date toSqlDate(int month, int day, int year) {
        java.util.Date newDate = toDate(month, day, year, 0, 0, 0);
        return newDate != null ? new java.sql.Date(newDate.getTime()) : null;
    }

    /**
     * Converts a time String into a java.sql.Time
     *
     * @param time
     *            The time String: either HH:MM or HH:MM:SS
     * @return A java.sql.Time made from the time String
     */
    public static java.sql.Time toSqlTime(String time) {
        java.util.Date newDate = toDate("1/1/1970", time);
        return newDate != null ? new java.sql.Time(newDate.getTime()) : null;
    }

    /**
     * Makes a java.sql.Time from separate Strings for hour, minute, and second.
     *
     * @param hourStr
     *            The hour String
     * @param minuteStr
     *            The minute String
     * @param secondStr
     *            The second String
     * @return A java.sql.Time made from separate Strings for hour, minute, and
     *         second.
     */
    public static java.sql.Time toSqlTime(String hourStr, String minuteStr,
                                          String secondStr) {
        java.util.Date newDate = toDate("0", "0", "0", hourStr, minuteStr,
                secondStr);
        return newDate != null ? new java.sql.Time(newDate.getTime()) : null;
    }

    /**
     * Makes a java.sql.Time from separate ints for hour, minute, and second.
     *
     * @param hour
     *            The hour int
     * @param minute
     *            The minute int
     * @param second
     *            The second int
     * @return A java.sql.Time made from separate ints for hour, minute, and
     *         second.
     */
    public static java.sql.Time toSqlTime(int hour, int minute, int second) {
        java.util.Date newDate = toDate(0, 0, 0, hour, minute, second);
        return newDate != null ? new java.sql.Time(newDate.getTime()) : null;
    }

    /**
     * Converts a date and time String into a Timestamp
     *
     * @param dateTime
     *            A combined data and time string in the format "MM/DD/YYYY
     *            HH:MM:SS", the seconds are optional
     * @return The corresponding Timestamp
     */
    public static java.sql.Timestamp toTimestamp(String dateTime) {
        java.util.Date newDate = toDate(dateTime);
        return newDate != null ? new java.sql.Timestamp(newDate.getTime()) : null;
    }

    /**
     * Converts a date String and a time String into a Timestamp
     *
     * @param date
     *            The date String: MM/DD/YYYY
     * @param time
     *            The time String: either HH:MM or HH:MM:SS
     * @return A Timestamp made from the date and time Strings
     */
    public static java.sql.Timestamp toTimestamp(String date, String time) {
        java.util.Date newDate = toDate(date, time);
        return newDate != null ? new java.sql.Timestamp(newDate.getTime()) : null;
    }

    /**
     * Makes a Timestamp from separate Strings for month, day, year, hour,
     * minute, and second.
     *
     * @param monthStr
     *            The month String
     * @param dayStr
     *            The day String
     * @param yearStr
     *            The year String
     * @param hourStr
     *            The hour String
     * @param minuteStr
     *            The minute String
     * @param secondStr
     *            The second String
     * @return A Timestamp made from separate Strings for month, day, year,
     *         hour, minute, and second.
     */
    public static java.sql.Timestamp toTimestamp(String monthStr,
                                                 String dayStr, String yearStr, String hourStr, String minuteStr,
                                                 String secondStr) {
        java.util.Date newDate = toDate(monthStr, dayStr, yearStr, hourStr,
                minuteStr, secondStr);
        return newDate != null ? new java.sql.Timestamp(newDate.getTime()) : null;
    }

    /**
     * Makes a Timestamp from separate ints for month, day, year, hour, minute,
     * and second.
     *
     * @param month
     *            The month int
     * @param day
     *            The day int
     * @param year
     *            The year int
     * @param hour
     *            The hour int
     * @param minute
     *            The minute int
     * @param second
     *            The second int
     * @return A Timestamp made from separate ints for month, day, year, hour,
     *         minute, and second.
     */
    public static java.sql.Timestamp toTimestamp(int month, int day, int year,
                                                 int hour, int minute, int second) {
        java.util.Date newDate = toDate(month, day, year, hour, minute, second);
        return newDate != null ? new java.sql.Timestamp(newDate.getTime()) : null;
    }

    /**
     * Converts a date and time String into a Date
     *
     * @param dateTime
     *            A combined data and time string in the format "MM/DD/YYYY
     *            HH:MM:SS", the seconds are optional
     * @return The corresponding Date
     */
    public static java.util.Date toDate(String dateTime) {
        // dateTime must have one space between the date and time...
        String date = dateTime.substring(0, dateTime.indexOf(" "));
        String time = dateTime.substring(dateTime.indexOf(" ") + 1);
        return toDate(date, time);
    }

    /**
     * Converts a date String and a time String into a Date
     *
     * @param date
     *            The date String: MM/DD/YYYY
     * @param time
     *            The time String: either HH:MM or HH:MM:SS
     * @return A Date made from the date and time Strings
     */
    public static java.util.Date toDate(String date, String time) {
        if (date == null || time == null) {
            return null;
        }
        String month;
        String day;
        String year;
        String hour;
        String minute;
        String second;

        int dateSlash1 = date.indexOf("/");
        int dateSlash2 = date.lastIndexOf("/");

        if (dateSlash1 <= 0 || dateSlash1 == dateSlash2) {
            return null;
        }
        int timeColon1 = time.indexOf(":");
        int timeColon2 = time.lastIndexOf(":");

        if (timeColon1 <= 0) {
            return null;
        }
        month = date.substring(0, dateSlash1);
        day = date.substring(dateSlash1 + 1, dateSlash2);
        year = date.substring(dateSlash2 + 1);
        hour = time.substring(0, timeColon1);

        if (timeColon1 == timeColon2) {
            minute = time.substring(timeColon1 + 1);
            second = "0";
        } else {
            minute = time.substring(timeColon1 + 1, timeColon2);
            second = time.substring(timeColon2 + 1);
        }
        return toDate(month, day, year, hour, minute, second);
    }

    /**
     * Makes a Date from separate Strings for month, day, year, hour, minute,
     * and second.
     *
     * @param monthStr
     *            The month String
     * @param dayStr
     *            The day String
     * @param yearStr
     *            The year String
     * @param hourStr
     *            The hour String
     * @param minuteStr
     *            The minute String
     * @param secondStr
     *            The second String
     * @return A Date made from separate Strings for month, day, year, hour,
     *         minute, and second.
     */
    public static java.util.Date toDate(String monthStr, String dayStr,
                                        String yearStr, String hourStr, String minuteStr, String secondStr) {
        int month, day, year, hour, minute, second;

        try {
            month = Integer.parseInt(monthStr);
            day = Integer.parseInt(dayStr);
            year = Integer.parseInt(yearStr);
            hour = Integer.parseInt(hourStr);
            minute = Integer.parseInt(minuteStr);
            second = Integer.parseInt(secondStr);
        } catch (Exception e) {
            return null;
        }
        return toDate(month, day, year, hour, minute, second);
    }

    /**
     * Makes a Date from separate ints for month, day, year, hour, minute, and
     * second.
     *
     * @param month
     *            The month int
     * @param day
     *            The day int
     * @param year
     *            The year int
     * @param hour
     *            The hour int
     * @param minute
     *            The minute int
     * @param second
     *            The second int
     * @return A Date made from separate ints for month, day, year, hour,
     *         minute, and second.
     */
    public static java.util.Date toDate(int month, int day, int year, int hour,
                                        int minute, int second) {
        Calendar calendar = Calendar.getInstance();

        try {
            calendar.set(year, month - 1, day, hour, minute, second);
        } catch (Exception e) {
            return null;
        }
        return new java.util.Date(calendar.getTime().getTime());
    }

    /**
     * Makes a date String in the format MM/DD/YYYY from a Date
     *
     * @param date
     *            The Date
     * @return A date String in the format MM/DD/YYYY
     */
    public static String toDateString(java.util.Date date) {
        if (date == null) {
            return "";
        }
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int year = calendar.get(Calendar.YEAR);
        String monthStr;
        String dayStr;
        String yearStr;

        if (month < 10) {
            monthStr = "0" + month;
        } else {
            monthStr = "" + month;
        }
        if (day < 10) {
            dayStr = "0" + day;
        } else {
            dayStr = "" + day;
        }
        yearStr = "" + year;
        return monthStr + "/" + dayStr + "/" + yearStr;
    }

    /**
     * 得到格式化的日期字符串
     *
     * @param d
     * @return 日期
     */
    public static String toDateString(java.util.Date d, String pattern) {

        String rs = "";

        try {
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            rs = formatter.format(d);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isFirstStartDate(rs) ? "" : rs;
    }

    /**
     * Makes a time String in the format HH:MM:SS from a Date. If the seconds
     * are 0, then the output is in HH:MM.
     *
     * @param date
     *            The Date
     * @return A time String in the format HH:MM:SS or HH:MM
     */
    public static String toTimeString(java.util.Date date) {
        if (date == null) {
            return "";
        }
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        return (toTimeString(calendar.get(Calendar.HOUR_OF_DAY), calendar
                .get(Calendar.MINUTE), calendar.get(Calendar.SECOND)));
    }

    /**
     * Makes a time String in the format HH:MM:SS from a separate ints for hour,
     * minute, and second. If the seconds are 0, then the output is in HH:MM.
     *
     * @param hour
     *            The hour int
     * @param minute
     *            The minute int
     * @param second
     *            The second int
     * @return A time String in the format HH:MM:SS or HH:MM
     */
    public static String toTimeString(int hour, int minute, int second) {
        String hourStr;
        String minuteStr;
        String secondStr;

        if (hour < 10) {
            hourStr = "0" + hour;
        } else {
            hourStr = "" + hour;
        }
        if (minute < 10) {
            minuteStr = "0" + minute;
        } else {
            minuteStr = "" + minute;
        }
        if (second < 10) {
            secondStr = "0" + second;
        } else {
            secondStr = "" + second;
        }
        return second == 0 ? hourStr + ":" + minuteStr : hourStr + ":" + minuteStr + ":" + secondStr;
    }

    /**
     * Makes a combined data and time string in the format "MM/DD/YYYY HH:MM:SS"
     * from a Date. If the seconds are 0 they are left off.
     *
     * @param date
     *            The Date
     * @return A combined data and time string in the format "MM/DD/YYYY
     *         HH:MM:SS" where the seconds are left off if they are 0.
     */
    public static String toDateTimeString(java.util.Date date) {
        if (date == null) {
            return "";
        }
        String dateString = toDateString(date);
        String timeString = toTimeString(date);
        return dateString != null && timeString != null ? dateString + " " + timeString : "";
    }

    /**
     * Makes a Timestamp for the beginning of the month
     *
     * @return A Timestamp of the beginning of the month
     */
    public static java.sql.Timestamp monthBegin() {
        Calendar mth = Calendar.getInstance();

        mth.set(Calendar.DAY_OF_MONTH, 1);
        mth.set(Calendar.HOUR_OF_DAY, 0);
        mth.set(Calendar.MINUTE, 0);
        mth.set(Calendar.SECOND, 0);
        mth.set(Calendar.AM_PM, Calendar.AM);
        return new java.sql.Timestamp(mth.getTime().getTime());
    }

    /**
     * datetime is the String of System.currentTimeMillis()?1?7
     *
     */
    public static String getDateTimeDisp(String datetime) {
        if ((datetime == null) || (datetime.equals(""))) {
            return "";
        }

        DateFormat formatter = DateFormat.getDateTimeInstance(
                DateFormat.MEDIUM, DateFormat.MEDIUM);
        long datel = Long.parseLong(datetime);
        return formatter.format(new Date(datel));

    }

    /**
     * 计算时间差
     *
     * @param maxTime
     * @param minTime
     * @return 小时
     */
    public static float reckonDifference(Date maxTime, Date minTime) {
        float fatHour = 0;
        long lngMaxTime = (maxTime == null) ? 0 : maxTime.getTime();
        long lngMinTime = (minTime == null) ? 0 : minTime.getTime();

        float lngDifference = lngMaxTime - lngMinTime;
        lngDifference = Math.abs(lngDifference);

        fatHour = lngDifference / HOUR_MS_UNIT;

        return fatHour;
    }

    public static String getCurrDateStr(String format) {
        String result = "";
        if (StringUtils.isEmpty(format)) {
            return result;
        }

        java.util.Date d = new java.util.Date();
        java.text.DateFormat df = new java.text.SimpleDateFormat(format);
        result = df.format(d);
        return result;

    }

    /**
     * 指定一个日期加上n年后得到一个新日期
     *
     * @param sDate
     *            指定日期
     * @param addYear
     *            年数,负数为减去n年
     * @return
     */
    public static Date getNextDateAddYear(Date sDate, int addYear) {
        int year = sDate.getYear();
        // Log.debug("year:"+year);
        int month = sDate.getMonth();
        // Log.debug("month:"+month);
        int day = sDate.getDate();
        // Log.debug("day:"+day);
        int hour = sDate.getHours();
        int minutes = sDate.getMinutes();
        int second = sDate.getSeconds();

        year = year + 1900 + addYear;
        month = month + 1;
        return toDate(month, day, year, hour, minutes, second);
    }

    /**
     * 指定一个日期加上n月后得到一个新日期
     *
     * @param sDate
     * @param addMonth
     *            月数,负数为减去n月
     * @return
     */
    public static Date getNextDateAddMonth(Date sDate, int addMonth) {
        int year = sDate.getYear();
        // Log.debug("year:"+year);
        int month = sDate.getMonth();
        // Log.debug("month:"+month);
        int day = sDate.getDate();
        // Log.debug("day:"+day);
        int hour = sDate.getHours();
        int minutes = sDate.getMinutes();
        int second = sDate.getSeconds();

        // 增加或减少多少年
        int addYear = addMonth / 12;
        int addMonthByYear = addMonth % 12;

        year = year + 1900 + addYear;
        month = month + 1 + addMonthByYear;
        return toDate(month, day, year, hour, minutes, second);
    }

    /**
     * 指定一个日期加上n天后得到一个新日期
     *
     * @param sDate
     *            天数,负数为减去n天
     * @param addDay
     * @return
     */
    public static Date getNextDateAddDay(Date sDate, int addDay) {
        Long lngTime = sDate.getTime();
        // 间隔的毫秒数
        Long addDayMSec = addDay * DAY_SEC_NUMBER * 1000;
        return new Date(lngTime + addDayMSec);
    }

    /**
     * 指定一个日期加上n小时后得到一个新日期
     *
     * @param sDate
     *            小时数,负数为减去n小时
     * @param addHour
     * @return
     */
    public static Date getNextDateAddHour(Date sDate, int addHour) {
        Long lngTime = sDate.getTime();
        // 间隔的毫秒数
        Long addHourMSec = addHour * HOUR_SEC_NUMBER * 1000;
        return new Date(lngTime + addHourMSec);
    }

    /**
     * <p>
     * 系统当前日期时间根据指定的格式时行处理，本方法会根据用户输入的format条件进行格式化，与格式无关的数据不进行转换。
     * </p>
     *
     * @param format
     *            指定的格式。
     *
     * @return 系统当前日期时间字符串
     */
    public static String currDateFormat(String format) {
        Date now = new Date();
        SimpleDateFormat f = new SimpleDateFormat(format);
        return f.format(now);
    }

    /**
     * 将{@link java.util.Date}类型转换为指定的字符串格式<br>
     *
     * @param date
     *            要转换的日期。
     * @param format
     *            指定的格式。
     * @return 指定格式日期型字符串。
     */
    public static String dateToStr(Date date, String format) {
        SimpleDateFormat f = new SimpleDateFormat(format);
        return f.format(date);
    }

    /**
     * 字符串转换为{@link java.util.Date}<br>
     *
     * @param time
     *            要转换的日期字符串。
     * @param format
     *            指定的格式。
     * @return Date 日期。
     */

    public static Date strToDate(String time, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date = sdf.parse(time);
            return date;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前月的第一天
     *
     * @return String
     */
    public static String getFirstDayOfMonth() {
        String str = "";
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar currentDate = Calendar.getInstance();
            currentDate.set(Calendar.DATE, 1);// 设为当前月的1号
            str = dateFormat.format(currentDate.getTime());
            return str;
        } catch (Exception e) {
            return str;
        }
    }

    /**
     * 获取给定年给定月的最后一天
     *
     * @param year
     *            给定年
     * @param month
     *            给定月
     */
    public static String getLastDay(String year, String month) {
        String lastDay = "";
        if (year != null && !year.equals("") && month != null
                && !month.equals("")) {
            lastDay = year + month + getDays(year, month);
        }
        return lastDay;
    }

    /**
     * 获取给定年给定月的天数
     *
     * @param year
     *            给定年
     * @param month
     *            给定月
     */
    public static int getDays(String year, String month) {
        int dateOfMonth = 0;
        if (year != null && !year.equals("") && month != null
                && !month.equals("")) {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.YEAR, Integer.parseInt(year));
            cal.set(Calendar.MONTH, Integer.parseInt(month) - 1);// Java月份才0开始算
            dateOfMonth = cal.getActualMaximum(Calendar.DATE);
        }
        return dateOfMonth;
    }

    /**
     * 在指定日期上相加指定年数
     *
     * @param d
     * @param year
     * @return
     */
    public static Date addYear(Date d, int year) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + year);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上减去指定年数
     *
     * @param d
     * @param year
     * @return
     */
    public static Date subtractYear(Date d, int year) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - year);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上相加指定月数
     *
     * @param d
     * @param month
     * @return
     */
    public static Date addMonth(Date d, int month) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + month);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上减去指定月数
     *
     * @param d
     * @param month
     * @return
     */
    public static Date subtractMonth(Date d, int month) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - month);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上相加指定天数
     *
     * @param d
     * @param day
     * @return
     */
    public static Date addDay(Date d, int day) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + day);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上减去指定天数
     *
     * @param d
     * @param day
     * @return
     */
    public static Date subtractDay(Date d, int day) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - day);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上相加指定的分钟
     *
     * @param d
     * @param minute
     * @return
     */
    public static Date addMinute(Date d, int minute) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + minute);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 在指定日期上减去指定的分钟
     *
     * @param d
     * @param minute
     * @return
     */
    public static Date subtractMinute(Date d, int minute) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - minute);
            return calendar.getTime();
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 根据日期返回ORACLE中标准的TO_DATE()输出字符串。
     *
     * @param d
     *            日期
     * @return 字符串
     */
    public static String toDate(Date d) {
        return " TO_DATE('" + dateToStr(d, "yyyy-MM-dd HH:mm:ss")
                + "','YYYY-MM-DD HH24:MI:SS')";
    }

    /**
     * 获取当前月的最后一天
     *
     * @return
     */
    public static String getEndDayOfMonth() {
        String str = "";
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        cal.set(Calendar.DATE, 1);
        cal.roll(Calendar.DATE, -1);
        Date endTime = cal.getTime();
        str = datef.format(endTime);
        return str;
    }

    /**
     * 获取某月的最后一天
     *
     * @param date
     *            输入的日期
     * @param format
     *            输出的格式
     * @return 该日期对应月份的最后一天日期
     */
    public static String getLastDateOfMonth(Date date, String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal
                .getActualMaximum(Calendar.DAY_OF_MONTH));
        return dateToStr(cal.getTime(), format);
    }

    /**
     * 获得指定日期当前季度
     *
     * @param date
     * @return
     */
    public static int getSeason(Date date) {
        int month = date.getMonth();
        if (month >= 0 && month < 3) {
            return 1;
        } else if (month >= 3 && month < 6) {
            return 2;
        } else if (month >= 6 && month < 9) {
            return 3;
        } else if (month >= 9 && month < 12) {
            return 4;
        } else {
            return 0;
        }
    }

    public static void main(String[] args) {
        System.out.println(DateUtils.dateToStr(DateUtils.subtractMonth(
                DateUtils.strToDate("2010-04-01", "yyyy-MM-dd"), 1),
                "yyyy-MM"));
    }

    /**
     * 获得指定年份的第一天
     *
     * @param
     * @return
     */
    public static Date getYearFirst(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获得指定年份的最后一天
     *
     * @param
     * @return
     */
    public static Date getYearLast(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    /**
     * 获得指定时间段的每一天
     *
     * @param
     * @return
     */
    public static List<Date> findDates(Date dBegin, Date dEnd) {
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(dBegin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime()))  {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

    /**
     * LocalDateTime转String
     *
     * @param
     * @return
     */
    public static Date LocalDateTime2Str(LocalDateTime time){
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = time.atZone(zoneId);
        Date date = Date.from(zdt.toInstant());
        return date;
    }

    /**
     * 时间戳转date
     *
     * @param
     * @return
     */
    public static String stampToDate(String s){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * 获取当前时间
     * @return String yyyy-MM-dd
     */
    public static String getNowDate(){
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(date);
    }

    public static String format(Date date){
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return f.format(date);
    }

    /**
     * 当前时间第几周
     *
     * @param
     * @return
     */
    public static int getCurWeek(){
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(new Date());
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 当前年份
     *
     * @param
     * @return
     */
    public static Integer getSysYear() {
        Calendar date = Calendar.getInstance();
        Integer year = date.get(Calendar.YEAR);
        return year;
    }

    /**
     * 当前月份
     *
     * @param
     * @return
     */
    public static Integer getSysMonth() {
        Calendar date = Calendar.getInstance();
        Integer month = date.get(Calendar.MONTH) + 1;
        return month;
    }

    /**
     * 当前季度
     *
     * @param
     * @return
     */
    public static int getQuarter() {
        int season = 0;
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return season;
    }

    /**
     * 指定日期加上天数后的日期
     * @param num 为增加的天数
     * @param newDate 创建时间
     * @return
     * @throws ParseException
     */
    public static String plusDay(int num,String newDate) throws ParseException{
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date  currdate = format.parse(newDate);
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
        currdate = ca.getTime();
        String enddate = format.format(currdate);
        return enddate;
    }

    /**
     * 指定日期加上天数后的日期
     * @param num 为增加的天数
     * @param newDate 创建时间
     * @return
     * @throws ParseException
     */
    public static Date plusDay(int num,Date newDate) throws ParseException{
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
        newDate = ca.getTime();
        return newDate;
    }

    /**
     * 获取明天的日期
     *
     * @param date
     * @return
     */
    public static Date getTomorrow(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +1);
        date = calendar.getTime();
        return date;
    }

    /**
     * 获取昨天的日期
     *
     * @param date
     * @return
     */
    public static Date getYesterday(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        date = calendar.getTime();
        return date;
    }
}

